Brian Wagner | Blog

Building a Local Development Server with Nginx

Jul 20, 2016 | Last edit: Dec 11, 2017

Developing on dedicated servers is a real luxury, especially after years of doing it with localhost on my own computer. No need to share computer resources. No need to worry that localhost settings are different from a real server. It is a real server! Even better, I can fill it up with as many dev sites as I need.

Recently I started working on a project with this set-up, providing for multiple developers to have various instances to do their work and testing. Add to that S3 integration for file management. It's a dream, and I wanted to have some of that for myself.

In this case, we were using Nginx, instead of the traditional Apache, so I decided to build a local server that would use that. Clear my afternoon, this may take some time.

Much of this is elementary at this point. I chose Ubuntu 16, and there are plenty of tutorials on installing Ubuntu server. Then I install, ssh, nginx and some php components on there to get it working.

With the easy part out of the way, on to the trickier part of configuring for multiple sites. 

Here's one good tutorial. The basic process is this:

1. Create directories for the individual sites in the /var/www/html directory.

2. Change owner and group settings on those directories to www-data.

sudo chown -R www-data:www-data /var/www/html/new_dir

3. Create or modify the server settings in /etc/nginx/sites-available. For a server on my local network, server_name doesn't matter because it's not handling actual outside requests. But there are two key settings: set the root directory path to match what's in /var/www/html.

server {
    ...
    root /var/www/html/new_dir
    ...
}

AND the big trick I had to figure out is to assign different ports for different sites. This is how we can use different URL's to get to the different sites on the server. So instead of

server {
    "listen 80;"
    ....
}

we can set one server to

server {
    "listen 8888;"
    "listen [::]:8888;"
    ...
}

and another to

server {
    "listen 9999;"
    "listen [::]:9999;"
    ...
}

4. Add a link to the new server configuration in the sites-enabled directory.

5. Restart Nginx and we're done. Live production servers require a couple more steps to resolve the incoming IP requests.

Now navigate to 192.168.1.10 in the browser and we get the site that's configured at the root of html and listening on port 80. We can find the other sites at 

192.168.1.10:8888

or 

192.168.1.10:9999

Ok, so we're getting there. Now a couple of Drupal specific things.

First we need to tell the server to listen for php requests, in that server configuration. We're adding "index.php" if it's not there. And uncomment the lines relevant to fastcgi.

server {
  ...
  # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;
 
  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
  } ...
  

My last trick was to find the correct recommended settings from Nginx to enable clean urls for Drupal. Nginx has a whole config file you can download. The recipe is here. I didn't need it all since it's not a live site. But the two key lines are these:  

server {
  ...
  location / {
     try_files $uri /index.php?$query_string; # For Drupal >= 7
  }
  location @drupal {
    rewrite ^(.*)$ /index.php?q=$1 last;
  } ...
  

That's it. I hope future me remembers all these steps. And if not, these notes can guide me.